/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package persistence.services;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;
import org.apache.commons.logging.Log;
import utils.BaseModel;
import utils.SmLogFactory;

/**
 *
 * @author gurgel
 */
public abstract class BaseDao implements Serializable {

    private static final Log log = SmLogFactory.getLog(BaseDao.class);
    private SortedMap<Integer, BaseModel> cacheById = new TreeMap();

    protected abstract BaseModel loadColumns(ResultSet rs) throws SQLException, PersistenceException;

    protected void addCache(BaseModel elemento) {
        cacheById.put(elemento.getId(), elemento);
    }

    public void clear() {
        cacheById.clear();
    }

    protected BaseModel getCache(int id) {
        return (cacheById.get(id));
    }

    protected SortedMap<Integer, BaseModel> getCache() {
        return cacheById;
    }

    protected boolean isCache(int id) {
        return (cacheById.get(id) != null);
    }

    protected BaseModel get(int id, String query) throws PersistenceException {
        BaseModel ret = null;
        if (isCache(id)) {
            return getCache(id);
        } else {
            //log.trace("Get BaseModel: " + id);
            try {
                PreparedStatement pstm = SmDatabase.prepareStatement(query);
                pstm.setInt(1, id);
                ResultSet rs = pstm.executeQuery();
                while (rs.next()) {
                    BaseModel carrega = loadColumns(rs);
                    addCache(carrega);
                    ret = carrega;
                }
                SmDatabase.cleanUp(pstm, rs);
            } catch (SQLException ex) {
                throw new UnsupportedOperationException("Db Error", ex);
            }
        }
        return ret;
    }

    public List<BaseModel> list(String query, String idColumnName) throws PersistenceException {
        //log.trace("Loading BaseModels:");
        List<BaseModel> retList = new ArrayList();
        try {
            PreparedStatement pstm = SmDatabase.prepareStatement(query);
            ResultSet rs = pstm.executeQuery();
            while (rs.next()) {
                BaseModel element;
                final int id = rs.getInt(idColumnName);
                if (isCache(id)) {
                    element = getCache(id);
                } else {
                    element = loadColumns(rs);
                    addCache(element);
                }
                retList.add(element);
            }
            SmDatabase.cleanUp(pstm, rs);
        } catch (SQLException ex) {
            throw new UnsupportedOperationException("Db Error", ex);
        }
        return retList;
    }

    public List<BaseModel> list(PreparedStatement pstm, String idColumnName) throws PersistenceException {
        //log.trace("Loading BaseModels:");
        List<BaseModel> retList = new ArrayList();
        try {
            ResultSet rs = pstm.executeQuery();
            while (rs.next()) {
                BaseModel element;
                final int id = rs.getInt(idColumnName);
                if (isCache(id)) {
                    element = getCache(id);
                } else {
                    element = loadColumns(rs);
                    addCache(element);
                }
                retList.add(element);
            }
            SmDatabase.cleanUp(pstm, rs);
        } catch (SQLException ex) {
            throw new UnsupportedOperationException("Db Error", ex);
        }
        return retList;
    }
}
